package com.caigou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.caigou.bean.cms.entity.FriendshipLink;
import com.caigou.bean.cms.entity.LinkType;
import com.caigou.bean.cms.param.FriendshipLinkParam;
import com.caigou.bean.cms.param.LinkTypeParam;
import com.caigou.component.HtmlBuilderComponent;
import com.caigou.mapper.cms.FriendshipLinkMapper;
import com.caigou.mapper.cms.LinkTypeMapper;
import com.caigou.service.FriendshipLinkService;
import com.caigou.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service("friendshipLinkService")
public class FriendshipLInkServiceImpl implements FriendshipLinkService {

    @Resource
    private FriendshipLinkMapper friendshipLinkMapper;

    @Resource
    private LinkTypeMapper linkTypeMapper;

    @Resource
    private HtmlBuilderComponent htmlBuilderComponent;

    public FriendshipLink selectByPrimaryKey(Integer id){
        return friendshipLinkMapper.selectByPrimaryKey(id);
    }

    public int deleteByPrimaryKey(Integer id){
        return friendshipLinkMapper.deleteByPrimaryKey(id);
    }

    public List<FriendshipLink> listFriendshipLink(){
        return friendshipLinkMapper.listFriendshipLink();
    }

    public int insertSelective(FriendshipLink friendshipLink){
        return friendshipLinkMapper.insertSelective(friendshipLink);
    }

    public int updateFriendshipLink(FriendshipLink friendshipLink){
        return friendshipLinkMapper.updateFriendshipLink(friendshipLink);
    }

    public Result saveFriendshipLink(FriendshipLinkParam friendshipLinkParam){
        FriendshipLink friendshipLink = new FriendshipLink();
        BeanUtil.copyProperties(friendshipLinkParam, friendshipLink);
        long timestamp = System.currentTimeMillis();
        Date current = new Date(timestamp);
        friendshipLink.setCreateTime(current);
        friendshipLink.setUpdateTime(current);
        Integer maxRank = friendshipLinkMapper.selectMaxRank();
        if(maxRank==null){
            maxRank = 0;
        }
        friendshipLink.setRank(maxRank+1);
        int result = 0;
        try{
            result = friendshipLinkMapper.insertSelective(friendshipLink);
        }catch(DataAccessException e) {
            if (e.getMessage().contains("Data too long")) {
                return Result.custom(400, "友情链接名称或者跳转链接超长", "友情链接名称或者跳转链接超长");
            }else if(e.getMessage().contains("Duplicate entry")){
                return Result.custom(400, "友情链接名称重复", "友情链接名称重复");
            }else {
                return Result.custom(400, "增加友情链接失败-数据库操作错误", "增加友情链接失败-数据库操作错误");
            }
        }
        if(result>0){
            //判断该友情链接类型的hasLink是否为1，即该类型下是否已经有友情链接
            LinkType linkType = linkTypeMapper.selectByPrimaryKey(friendshipLink.getLinkTypeId());
            if(linkType!=null && linkType.getHasLink()!=1){
                linkType.setHasLink(1);
                linkType.setUpdateTime(current);
                int result2 = linkTypeMapper.updateLinkType(linkType);
                log.info("设置链接类型为{}的hasLink为1，结果={}", linkType.getId(), result2);
            }
            return Result.success("增加友情链接成功");
        }else{
            return Result.error("增加友情链接失败");
        }
    }

    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class })
    public Result updateFriendshipLink(FriendshipLinkParam param){
        FriendshipLink oldFriendshipLink = friendshipLinkMapper.selectByPrimaryKey(param.getId());
        if(oldFriendshipLink==null){
            return Result.error("没有这个友情链接");
        }
        FriendshipLink friendshipLink = new FriendshipLink();
        BeanUtil.copyProperties(param, friendshipLink);
        friendshipLink.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = 0;
        try{
            result = friendshipLinkMapper.updateFriendshipLink(friendshipLink);
        }catch(DataAccessException e) {
            if (e.getMessage().contains("Data too long")) {
                return Result.custom(400, "友情链接名称或者跳转链接超长", "友情链接名称或者跳转链接超长");
            }else if(e.getMessage().contains("Duplicate entry")){
                return Result.custom(400, "友情链接名称重复", "友情链接名称重复");
            }else {
                return Result.custom(400, "更新友情链接失败-数据库操作错误", "更新友情链接失败-数据库操作错误");
            }
        }
        if(result>0){
            //修改原友情链接的类型hasLink
            Integer oldLinkTypeId = oldFriendshipLink.getLinkTypeId();
            if(oldLinkTypeId!=null){
                int count = friendshipLinkMapper.getFriendshipLinkCountByLinkTypeId(oldLinkTypeId);
                if(count==0){
                    LinkType linkType = new LinkType();
                    linkType.setId(oldLinkTypeId);
                    linkType.setHasLink(0);
                    linkType.setUpdateTime(new Date(System.currentTimeMillis()));
                    int result2 = linkTypeMapper.updateLinkType(linkType);
                    log.info("更新原linkTypeId={}的hasLink为0，结果={}", oldLinkTypeId, result2);
                }
            }
            //修改新友情链接类型hasLink
            Integer linkTypeId = friendshipLink.getLinkTypeId();
            if(linkTypeId!=null){
                int count = friendshipLinkMapper.getFriendshipLinkCountByLinkTypeId(linkTypeId);
                if(count>0){
                    LinkType linkType = new LinkType();
                    linkType.setId(linkTypeId);
                    linkType.setHasLink(1);
                    linkType.setUpdateTime(new Date(System.currentTimeMillis()));
                    int result2 = linkTypeMapper.updateLinkType(linkType);
                    log.info("更新新linkTypeId={}的hasLink为0，结果={}", oldLinkTypeId, result2);
                }
            }
            return Result.success("更新友情链接成功");
        }else{
            return Result.error("更新友情链接失败");
        }
    }


    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class })
    public Result deleteFriendshipLink(FriendshipLinkParam friendshipLinkParam){
        FriendshipLink friendshipLink = friendshipLinkMapper.selectByPrimaryKey(friendshipLinkParam.getId());
        if(friendshipLink==null){
            return Result.error("没有这个友情链接");
        }
        int result = friendshipLinkMapper.deleteByPrimaryKey(friendshipLinkParam.getId());
        if(result>0){
            //更新rank值，保证连续
            int result2 = friendshipLinkMapper.updateRankForDelete(friendshipLink.getRank());
            log.info("updateRankForDelete for rank={}, result={}", friendshipLink.getRank(), result2);
            //更新链接类型的hasLink值
            Integer linkTypeId = friendshipLink.getLinkTypeId();
            int count = friendshipLinkMapper.getFriendshipLinkCountByLinkTypeId(linkTypeId);
            if(count==0){//该类型下没有友情链接
                LinkType linkType = linkTypeMapper.selectByPrimaryKey(linkTypeId);
                linkType.setHasLink(0);
                linkType.setUpdateTime(new Date(System.currentTimeMillis()));
                int result3 = linkTypeMapper.updateLinkType(linkType);
                log.info("设置友情链接类型id={}的hasLink=0的结果={}", linkTypeId, result3);
            }
            return Result.success("删除友情链接成功");
        }else{
            return Result.error("删除友情链接失败");
        }
    }

    @Transactional(transactionManager = "txManager", propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class })
    public synchronized Result moveFriendshipLink(FriendshipLinkParam param){
        FriendshipLink fromFriendshipLink = friendshipLinkMapper.selectByPrimaryKey(param.getId());
        if(fromFriendshipLink==null){
            return Result.error("没有这个源友情链接");
        }
        int toRank = param.getToRank();
        FriendshipLink toFriendshipLink = friendshipLinkMapper.getByRank(toRank);
        if(toFriendshipLink==null){
            return Result.error("没有这个目标友情链接");
        }

        int fromRank = fromFriendshipLink.getRank();
        if(fromRank==toRank){
            return Result.error("源目标与移动目标相同，无需移动");
        }
        fromFriendshipLink.setRank(toRank);
        fromFriendshipLink.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = friendshipLinkMapper.updateFriendshipLink(fromFriendshipLink);
//        int zero = 1/0;
        if(result>0){
            int count = 0;
            param.setFromRank(fromRank);
            if(fromRank<toRank) {//向后移动
                count = friendshipLinkMapper.updateRankForBack(param);
                log.info("id={}， fromRank={}， toRank={}向后移动结果={}", param.getId(), fromRank, toRank, count);
            }else if(fromRank>toRank){//向前移动
                count = friendshipLinkMapper.updateRankForFront(param);
                log.info("id={}， fromRank={}， toRank={}向前移动结果={}", param.getId(), fromRank, toRank, count);
            }
            if(count>0) {
                return Result.success("友情链接移动成功");
            }else{
                return Result.error("友情链接移动失败");
            }
        }else{
            return Result.error("友情链接移动失败");
        }
    }

    public Result publishFriendshipLink(){
        //生成友情链接页面
        String friendshipLink = htmlBuilderComponent.buildFriendshipLinkHtml();
        //生成footer碎片
        String footer = htmlBuilderComponent.buildFooterHtml();

        if(null != footer && null != friendshipLink){
            return Result.success("发布友情链接页面成功");
        }else{
            return Result.error("发布友情链接页面失败");
        }

    }

    public Result saveLinkType(LinkTypeParam param){
        LinkType linkType = new LinkType();
        BeanUtil.copyProperties(param, linkType);
        long timestamp = System.currentTimeMillis();
        Date current = new Date(timestamp);
        linkType.setCreateTime(current);
        linkType.setUpdateTime(current);
        int result = linkTypeMapper.insertSelective(linkType);
        if(result>0){
            return Result.success("增加链接类型成功");
        }else{
            return Result.error("增加链接类型失败");
        }
    }

    public Result deleteLinkType(LinkTypeParam param){
        LinkType linkType = linkTypeMapper.selectByPrimaryKey(param.getId());
        if(linkType.getHasLink()!=0){
            return Result.error("该类型下有友情链接，不能删除");
        }
        int result = linkTypeMapper.deleteByPrimaryKey(param.getId());
        if(result>0){
            return Result.success("删除链接类型成功");
        }else{
            return Result.error("删除链接类型失败");
        }
    }

    public Result listLinkType(Integer hasLink){
        List<LinkType> list = linkTypeMapper.listLinkType(hasLink);
        return Result.success(list);
    }

    public Result updateLinkType(LinkTypeParam param){
        LinkType linkType = new LinkType();
        BeanUtil.copyProperties(param, linkType);
        linkType.setUpdateTime(new Date(System.currentTimeMillis()));
        int result = linkTypeMapper.updateLinkType(linkType);
        if(result>0){
            return Result.success("修改链接类型成功");
        }else{
            return Result.error("修改链接类型失败");
        }
    }
}
